package gcontent.channel.http;
import gcontent.utils.URLUtils;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.apache.log4j.Logger;

public class CookieManager {

	private HashMap<String, ArrayList<CookieEntry>> cookie_reg = new HashMap<String, ArrayList<CookieEntry>>();
	
	private static Logger log = Logger.getLogger(CookieManager.class);
	
	public static String getRootDomain(String domain)
	{		
		int n_dots;

		n_dots = 0;
		
		for(int i = domain.length() - 1; i >= 0; i--) {
			if(domain.charAt(i) == '.') {								
				if(n_dots == 1) {
					return domain.substring(i + 1);
				}
				
				n_dots++;
			}
		}						
		
		return domain;
	}
		
	/* put a new cookie */
	public CookieEntry putCookie(URL url_dst, String cookie)
	{		
		CookieEntry cookie_ent;
		String root_domain;
		ArrayList<CookieEntry> cookie_values;
		
		if(log.isDebugEnabled())
			log.debug("cookie => " + cookie + " url => " + url_dst.toString());
	
		/* parse cookie */
		cookie_ent = parseCookie(url_dst, cookie);
		
		/* get root domain of cookie domain */
		root_domain = URLUtils.getDomainToken(cookie_ent.getDomain(), 1);
		
		/* get cookies array of this root domain and put this new cookie into arraylist */
		cookie_values = this.cookie_reg.get(root_domain);
		if(cookie_values == null) {
			cookie_values = new ArrayList<CookieEntry>();
			this.cookie_reg.put(root_domain, cookie_values);
		}
		
		cookie_values.add(cookie_ent);	
		
		return cookie_ent;
	}
	
	public String getCookieStr(HashMap<String, String> res_cookie_vals)
	{
		String ret_nameval;

		ret_nameval = "";		
		for(Iterator<String> it = res_cookie_vals.keySet().iterator(); it.hasNext(); ) {
			String name, value;

			name = it.next();
			value = res_cookie_vals.get(name);

			ret_nameval += name + "=" + value + "; "; 

		}
		
		if(ret_nameval.length() > 0)
			ret_nameval = ret_nameval.substring(0, ret_nameval.length() - 2);

		return ret_nameval;
	}
	
	/* get a cookie registered */
	public String getCookieValues(URL url_dst)
	{
		ArrayList<CookieEntry> cookie_arr;
		String host_dst, dir_dst;
		HashMap<String, String> res_cookie_vals;
		String ret_cookie;
		
		host_dst = url_dst.getHost();
		
		cookie_arr = this.cookie_reg.get(URLUtils.getDomainToken(host_dst, 1));
		if(cookie_arr == null)
			return null;
		
		host_dst = url_dst.getHost();
		dir_dst = URLUtils.getDirectory(url_dst.getPath());

		res_cookie_vals = new HashMap<String, String>();
		
		for(int i = 0; i < cookie_arr.size(); i++) {
			CookieEntry cookie_ent;
			
			cookie_ent = cookie_arr.get(i);
						
			if(!cookie_ent.isExpired() &&					
				cookie_ent.inDomain(host_dst) && 
				cookie_ent.inPath(dir_dst) 
			  ) {
				/* cookie values */
				cookie_ent.getValues(res_cookie_vals);
			}			
			
		}
		
		/* get cookie */
		ret_cookie = getCookieStr(res_cookie_vals);
		if(log.isDebugEnabled())
			log.debug("return cookie => " + ret_cookie + " url => " + url_dst.toString());
		
		return ret_cookie;
	}
	
	private CookieEntry parseCookie(URL url_dst, String cookie_value)
	{
		String name_value[];
		CookieEntry cookie_ent;
		
		cookie_ent = new CookieEntry();
		name_value = cookie_value.split(";");
		
		for(int i = 0; i < name_value.length; i++) {
			String name;
			String value;
			int delim;
			
			delim = name_value[i].indexOf("=");
			if(delim > -1) {
				if(name_value[i].indexOf(' ') == 0) {
					name = name_value[i].substring(1, delim);
				} else {
					name = name_value[i].substring(0, delim);
				}				
				
				value = name_value[i].substring(delim + 1, name_value[i].length());
				
				if(name.equalsIgnoreCase("domain")) {
					cookie_ent.setDomain(value);
				} else if(name.equalsIgnoreCase("expires")) {
					cookie_ent.setExpires(value);					
				} else if(name.equalsIgnoreCase("path")) {
					cookie_ent.setPath(value);
				} else if(name.equalsIgnoreCase("version")) {
					;
				} else {
					cookie_ent.setValue(name, value);
				}
				/*
				System.out.println("name =>" + name);
				System.out.println("value =>" + value);
				*/
			}
			
		}
		
		/* set domain if not exist on cookie */
		if(cookie_ent.getDomain() == null)
			cookie_ent.setDomain(url_dst.getHost());
		
		/* set path to root if not exist on cookie */
		if(cookie_ent.getPath() == null)
			cookie_ent.setPath("/");
		
		return cookie_ent;
	}	
}
